package summoning2;

import impsoft.scripting.ibot.enums.InventorySlot;
import impsoft.scripting.ibot.itemrec.ItemCondition;

import java.awt.Color;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import base.DreamUtility;

public class FamiliarInventory extends DreamUtility {
	private Familiar familiar;
	private Summoning summoning;
	private static final Rectangle EXIT_INVENTORY = new Rectangle(417, 33, 16, 16);
	private static final Rectangle WITHDRAW_ALL = new Rectangle(411, 297, 29, 21);

	public FamiliarInventory(Familiar familiar, Summoning summoning) {
		super(summoning.getScript());

		this.familiar = familiar;
		this.summoning = summoning;
	}

	public boolean deposit(ItemCondition condition, int amount, boolean closeAfter) throws InterruptedException {
		if (!isInventoryUp()) {
			summoning.openFamiliarInventory();
		}

		if (isInventoryFull()) {
			return false;
		}

		while (cs.theTabs.Inventory.countEmptySlots() < 28 && !isInventoryFull()
				&& cs.getInventoryUtils().doInventory(condition, "Store-All", false).isSuccessful()) {
			cs.sleep(100);
		}

		if (closeAfter) {
			exit();
		}

		return false;
	}

	public boolean withdrawAll() throws InterruptedException {
		if (isInventoryUp() && !cs.theTabs.Inventory2.isFull()) {
			cs.mouseClickLeft(WITHDRAW_ALL);
		}

		return getEmptySlots() == 28;
	}

	public boolean withdraw(ItemCondition condition, int amount) throws InterruptedException {
		if (!isInventoryUp()) {
			cs.log(1);
			return false;
		}

		if (cs.theTabs.Inventory2.isFull()) {
			cs.log(2);
			return false;
		}

		if (count(condition) < 1) {
			cs.log(3);
			return false;
		}

		slots: for (int i = 0; i < amount; i++) {
			cs.log(i * 10);
			for (FamiliarItemSlot item : getItems()) {
				if (item.getItemName() != null && condition.validItem(item.getItemName())) {
					boolean breakLoop = false;
					cs.log(4);

					Rectangle area = item.getArea();
					if (area != null) {
						cs.paintRectangle(area, Color.RED, 5000);

						cs.mouseMove(area);
						if (cs.theTopText.isTopTextContaining("")) {
							cs.log(10);
							if (item.isStackable() && amount == item.getStackSize() || count(condition) == amount) {
								cs.mouseClickRight(cs.getCurrentMouseXY());

								if (cs.theMenuFinder.doMenuContains(Pattern.compile(".*Withdraw-all.*",
										Pattern.CASE_INSENSITIVE))) {
									cs.log("Withdrew items");
									breakLoop = true;
								}
							} else {
								cs.mouseClickRight(cs.getCurrentMouseXY());

								if (cs.theMenuFinder.doMenuContains(Pattern.compile(".*Withdraw-" + amount + ".*",
										Pattern.CASE_INSENSITIVE))) {
									cs.log("Withdrew items");
								}
							}
						}
					} else {
						cs.log("null rect");
					}

					if (breakLoop) {
						break slots;
					}
				}
			}
		}

		return false;
	}

	public int countStack(ItemCondition condition) throws InterruptedException {
		for (FamiliarItemSlot item : getItems()) {
			if (condition.validItem(item.getItemName())) {
				return item.getStackSize();
			}
		}

		return 0;
	}

	public int count(ItemCondition condition) throws InterruptedException {
		int count = 0;
		for (FamiliarItemSlot item : getItems()) {
			cs.log("itemName" + item.getItemName());
			if (item.getItemName() != null && condition.validItem(item.getItemName())) {
				count++;
			}
		}

		return count;
	}

	public FamiliarItemSlot[] getItems() {
		List<FamiliarItemSlot> itemSlots = new ArrayList<FamiliarItemSlot>();
		for (InventorySlot slot : InventorySlot.values()) {
			itemSlots.add(new FamiliarItemSlot(slot.index, getScript()));
		}

		return itemSlots.toArray(new FamiliarItemSlot[itemSlots.size()]);
	}

	public int getEmptySlots() {
		if (!isInventoryUp()) {
			return -1;
		} else {
			return familiar.getInventorySpcae();
		}
	}

	public boolean isInventoryFull() {
		return getEmptySlots() == 0;
	}

	public boolean isInventoryUp() {
		try {
			return cs.getInterfaceAtIndex(671, 28).isValid();
		} catch (Throwable t) {
			return false;
		}
	}

	public boolean exit() throws InterruptedException {
		if (isInventoryUp()) {
			cs.mouseClickLeft(EXIT_INVENTORY);
		}

		return !isInventoryUp();
	}
}
